package com.jmp.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jmp.api.service.CompanyAccountService;
import com.jmp.api.service.SunCodeService;
import com.jmp.api.service.WechatBaseService;
import com.jmp.autocofiguration.util.OssUtil2;
import lombok.extern.slf4j.Slf4j;
import one.stand.enums.LoginEnum;
import one.stand.mapper.GoodSpecMapperExt;
import one.stand.mapper.SysWxCodeMapperExt;
import one.stand.model.*;
import one.stand.service.BusinessCardBaseService;
import one.stand.service.GoodsBaseService;
import one.stand.service.RecordPublicService;
import one.stand.util.AssertUtil;
import one.stand.util.HttpUtil2;
import one.stand.util.ImageGenerateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Objects;

@Service
@Slf4j
public class SunCodeServiceImpl implements SunCodeService {
    //    private static final String url_wxCode = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
    private static final String url_wxCode = "https://api.weixin.qq.com/wxa/getwxacode?access_token=";

    @Autowired
    private WechatBaseService wechatBaseService;
    @Autowired
    private GoodsBaseService goodsBaseService;
    @Autowired
    private RecordPublicService recordPublicService;
    @Autowired
    private BusinessCardBaseService businessCardBaseService;
    @Autowired
    private GoodSpecMapperExt goodSpecMapperExt;

    @Autowired
    private SysWxCodeMapperExt sysWxCodeMapperExt;
    @Autowired
    private CompanyAccountService companyAccountService;

    @Override
    public String goodsSuncode(Integer specId, Integer cardId) {
        Assert.notNull(specId, "specId为空");

        String key = specId + ":" + cardId;
        String codeUrl = getCodeUrl(TYPE_GOODS, key);
        if (StringUtils.isNoneBlank(codeUrl)) {
            return codeUrl;
        }

        GoodSpec goodSpec = goodSpecMapperExt.selectByPrimaryKey(specId);
        Goods goods = goodsBaseService.getOn(goodSpec.getGoodsId());
        AssertUtil.nonNull(goods, "商品不存在");

        CompanyAccount companyAccountModel = companyAccountService.getDefaultIfNull(goods.getCompanyId(), LoginEnum.USER);

        Integer card = Objects.nonNull(cardId) ? cardId : businessCardBaseService.getBoosCardId(goods.getCompanyId());

        StringBuilder stringBuffer = new StringBuilder();
//            //名片id
//            stringBuffer.append("card=").append(card);
//            //公司id
//            stringBuffer.append("&c=").append(goods.getCompanyId());
//            //分类id
//            stringBuffer.append("&s=").append(specId);
//            //商品id
//            stringBuffer.append("&g=").append(goods.getGoodsId());

        stringBuffer.append("cardId=").append(card);
        stringBuffer.append("&companyId=").append(goods.getCompanyId());
        stringBuffer.append("&goodId=").append(goods.getGoodsId());

        final String page = "pages/prodDetail/main";
        String sunCodeUrl = getWxCode(stringBuffer.toString(), page, companyAccountModel.getAppId(), companyAccountModel.getAppSecret(), null);
        Assert.isTrue(StringUtils.isNoneBlank(sunCodeUrl), "生成太阳码失败");

        //添加名片
//            CompanyModel companyModel = companyBaseService.getById(commodityInfoEntity.getCompanyId());
        BusinessCard cardModel = businessCardBaseService.getCustomer(card);
        InputStream inputStream = ImageGenerateUtil.suncode(sunCodeUrl, cardModel.getLogo(), null);
        sunCodeUrl = OssUtil2.upload(inputStream, OssUtil2.FileSuffix.png);

        save(TYPE_GOODS, key, sunCodeUrl);

        return sunCodeUrl;
    }

    @Override
    public String getWxTwoCode(Integer cardId, boolean updateFlag) {
        String refId = String.valueOf(cardId);
        String codeUrl;
        if (!updateFlag) {
            codeUrl = getCodeUrl(TYPE_CARD, refId);
            if (StringUtils.isNoneBlank(codeUrl)) {
                return codeUrl;
            }
        }

        BusinessCard model = businessCardBaseService.getCustomer(cardId);
        codeUrl = getWxCode(cardId, model.getCompanyId(), model.getLogo(), null);

        save(TYPE_CARD, refId, codeUrl);

        return codeUrl;
    }

    @Override
    public String companyCode(Integer cardId, Integer companyId, String logo) {
        String refId = String.valueOf(companyId);
        String codeUrl = getCodeUrl(TYPE_COMPANY, refId);
        if (StringUtils.isNoneBlank(codeUrl)) {
            return codeUrl;
        }

        codeUrl = getWxCode(cardId, companyId, logo, 1280);

        save(TYPE_COMPANY, refId, codeUrl);

        return codeUrl;
    }

    @Override
    public String room(Integer roomId, Integer companyId) {
        String refId = String.valueOf(roomId);
        String codeUrl = getCodeUrl(TYPE_ROOM, refId);
        if (StringUtils.isNoneBlank(codeUrl)) {
            return codeUrl;
        }

        CompanyAccount companyAccountModel = companyAccountService.getDefaultIfNull(companyId, LoginEnum.USER);
        String path = recordPublicService.getLiveRoomWxUrl(roomId);
        codeUrl = getWxCode(path, companyAccountModel.getAppId(), companyAccountModel.getAppSecret(), 1280);

        save(TYPE_ROOM, refId, codeUrl);

        return codeUrl;
    }

    private String getWxCode(Integer cardId, Integer companyId, String cardImg, Integer width) {
        final String scene = "cardId=" + cardId + "&companyId=" + companyId;
        final String page = "pages/index/main";
        CompanyAccount companyAccountModel = companyAccountService.getDefaultIfNull(companyId, LoginEnum.USER);
        String twoCode = getWxCode(scene, page, companyAccountModel.getAppId(), companyAccountModel.getAppSecret(), width);

        //添加名片头像
        if (StringUtils.isNotBlank(twoCode)) {
            String cardUrl;
            if (StringUtils.isNoneBlank(cardImg)) {
                InputStream inputStream = ImageGenerateUtil.suncode(twoCode, cardImg, width);
                cardUrl = OssUtil2.upload(inputStream, OssUtil2.FileSuffix.png);
            } else {
                cardUrl = twoCode;
            }
            return cardUrl;
        }
        return null;
    }

    private String getWxCode(String scene, String page, String appId, String appSecret, Integer width) {
        return getWxCode(page + "?" + scene, appId, appSecret, width);
    }

    private String getWxCode(String path, String appId, String appSecret, Integer width) {
        try {
            String accessToken = wechatBaseService.getWxToken(appId, appSecret);
            log.info("获取到token:{}", accessToken);

            JSONObject json = new JSONObject();
//            json.put("page", page);
//            json.put("scene", scene);
            if (Objects.nonNull(width)) {
                json.put("width", width);
            }
            json.put("path", path);
            byte[] result = HttpUtil2.postBytes(url_wxCode + accessToken, json.toJSONString());
            if (Objects.nonNull(result) && result.length < 300) {
                log.warn("小程序码返回:{}", new String(result));
            }

            InputStream inputStream = new ByteArrayInputStream(result);
            String wxSunCode = OssUtil2.upload(inputStream, OssUtil2.FileSuffix.png);
            log.info("获取到太阳码：{}", wxSunCode);
            if (StringUtils.isBlank(wxSunCode)) {
                return null;
            }
            return wxSunCode;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private String getCodeUrl(Integer type, String refId) {
        SysWxCode sysWxCode = sysWxCodeMapperExt.selectByRefId(type, refId);
        if (Objects.nonNull(sysWxCode) && StringUtils.isNoneBlank(sysWxCode.getWxCode())) {
            return sysWxCode.getWxCode();
        }
        return null;
    }

    private void save(Integer type, String refId, String codeUrl) {
        SysWxCode sysWxCode = sysWxCodeMapperExt.selectByRefId(type, refId);
        if (Objects.nonNull(sysWxCode)) {
            SysWxCode sysWxCodeUpdate = new SysWxCode();
            sysWxCodeUpdate.setId(sysWxCode.getId());
            sysWxCodeUpdate.setWxCode(codeUrl);
            sysWxCodeMapperExt.updateByPrimaryKeySelective(sysWxCodeUpdate);
            return;
        } else {
            sysWxCode = new SysWxCode();
            sysWxCode.setType(type);
            sysWxCode.setRefId(refId);
            sysWxCode.setWxCode(codeUrl);
            sysWxCodeMapperExt.insertSelective(sysWxCode);
        }
    }
}
